package cfca.seal.web.action.sealCert;

import cfca.seal.bean.AdminUser;
import cfca.seal.bean.OperationLog;
import cfca.seal.bean.SealCert;
import cfca.seal.common.Page;
import cfca.seal.exception.CodeException;
import cfca.seal.mananger.OperationLogManager;
import cfca.seal.util.StringUtil;
import cfca.seal.web.service.OperationLogService;
import cfca.seal.web.service.SealCertService;
import cfca.seal.web.system.SessionManager;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

@Controller
@RequestMapping({"/sealCert"})
public class SealCertAction
{
  private String jumpListPagePath = "sys/sealCert/list.html";
  private String jumpAddPagePath = "sys/sealCert/add.html";
  private String jumpProduceP10PathForSoft = "sys/sealCert/producep10ForSoft.html";
  private String jumpProduceP10PathForHard = "sys/sealCert/producep10ForHard.html";
  private String jumpDowndloadP10Path = "sys/sealCert/downloadp10.html";
  private String jumpImportCertPath = "sys/sealCert/importcert.html";
  private String jumpCertDetailPath = "sys/sealCert/detail.html";
  private String jumplistdo = "redirect:/sealCert/v_list.do";

  @Resource
  private SealCertService sealCertService;

  @Resource
  private OperationLogService operationLogService;
  private static final Logger logger = LoggerFactory.getLogger("web_sys");

  @RequestMapping({"/v_list"})
  public String getAll(String pageNo, ModelMap modelMap, HttpServletRequest request) throws CodeException {
    try {
      AdminUser manager = SessionManager.getManager(request);
      List list = this.sealCertService.getSealCerts(manager);
      Page page = new Page(list.size());
      page.setBeans(list);
      modelMap.put("page", page);
      return this.jumpListPagePath;
    } catch (Exception e) {
      logger.error("查看印章证书列表出现系统错误", e);
      throw new CodeException("C0001", e);
    }
  }

  @RequestMapping({"/v_add"})
  public String viewAdd(ModelMap modelMap) throws CodeException {
    return this.jumpAddPagePath;
  }

  @RequestMapping(value={"/v_produceP10"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
  public String produceP10(String certID, ModelMap modelMap, HttpServletRequest request) throws CodeException {
    try {
      SealCert sealCert = this.sealCertService.getSealCertById(certID);
      modelMap.put("sealCert", sealCert);
      if ("JSOFT_LIB".equals(sealCert.getDevice()))
        return this.jumpProduceP10PathForSoft;
      if ("JHARD_LIB".equals(sealCert.getDevice()))
        return this.jumpProduceP10PathForHard;
    }
    catch (Exception e) {
      logger.error("产生p10出现系统错误", e);
      throw new CodeException("C0001", e);
    }
    return null;
  }

  @RequestMapping(value={"/o_produceP10"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
  public String submitProduceP10(String id, String password, String confirmPassword, String keyLength, ModelMap modelMap, HttpServletRequest request) throws CodeException
  {
    OperationLog operationLog = OperationLogManager.getInstance(request, "印章证书管理", "产生P10", "", "产生P10", null);
    operationLog.setOrganizationId(SessionManager.getManager(request).getOrganizationId());
    logger.info("产生P10(软证)");
    try
    {
      SealCert sealCert = this.sealCertService.getSealCertById(id);
      sealCert.setKeyLength(keyLength);
      this.sealCertService.generalReq(sealCert, password);

      modelMap.put("id", sealCert.getId());
      modelMap.put("alias", sealCert.getAlias());

      operationLog.setObjectId(sealCert.getAlias());
      logger.info(sealCert.getDevice() + "：产生证书申请书成功");
    } catch (CodeException e) {
      operationLog.setResult(10);
      logger.error("产生软证书申请书失败:", e);
      throw new CodeException(e.getCode(), e.getMessage());
    } catch (Exception e) {
      operationLog.setResult(10);
      logger.error("产生软证书申请书失败:", e);
      throw new CodeException("C0001", e.getMessage());
    } finally {
      this.operationLogService.addOperationLog(operationLog);
    }

    return this.jumpDowndloadP10Path;
  }

  @RequestMapping(value={"/o_produceP10ForHard"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
  public String submitProduceP10ForHard(String id, String keyID, String keyLength, ModelMap modelMap, HttpServletRequest request) throws CodeException {
    OperationLog operationLog = OperationLogManager.getInstance(request, "印章证书管理", "产生P10", "", "产生P10(带加密卡)", null);
    operationLog.setOrganizationId(SessionManager.getManager(request).getOrganizationId());
    logger.info("产生P10(带加密卡),密钥序号:" + keyID);
    try {
      SealCert sealCert = this.sealCertService.getSealCertById(id);
      sealCert.setKeyId(keyID);
      sealCert.setKeyLength(keyLength);
      this.sealCertService.generalReq(sealCert, "");

      modelMap.put("id", sealCert.getId());
      modelMap.put("alias", sealCert.getAlias());

      operationLog.setObjectId(sealCert.getAlias());
      logger.info(sealCert.getDevice() + "：产生硬件证书申请书成功");
    } catch (CodeException e) {
      operationLog.setResult(10);
      logger.error("产生硬证书申请书失败:", e);
      throw new CodeException(e.getCode(), e.getMessage());
    } catch (Exception e) {
      operationLog.setResult(10);
      logger.error("产生硬证书申请书失败:", e);
      throw new CodeException("C0001", e.getMessage());
    } catch (Throwable e) {
      operationLog.setResult(10);
      logger.error("产生硬证书申请书失败:", e);
      if (e.getMessage().contains("java.lang.UnsatisfiedLinkError: no device in java.library.path")) {
        throw new CodeException("C6009", "硬件设备(加密机/加密卡)不存在");
      }
      throw new CodeException("C0001", e.getMessage());
    } finally {
      this.operationLogService.addOperationLog(operationLog);
    }

    return this.jumpDowndloadP10Path;
  }

  @RequestMapping({"/o_download.do"})
  public void p10DownLoad(HttpServletRequest request, HttpServletResponse response) throws CodeException {
    OutputStream outputStream = null;
    try {
      String id = request.getParameter("id").trim();
      String type = request.getParameter("type").trim();
      SealCert sealCert = this.sealCertService.getSealCertById(id);

      byte[] data = "".getBytes();
      if ("req".equals(type))
        data = sealCert.getP10();
      else if ("cer".equals(type)) {
        data = sealCert.getPublickCertData();
      }
      response.reset();
      response.addHeader("Content-disposition", "attachment; filename=" + sealCert.getAlias() + "." + type);
      response.addHeader("Content-Length", "" + data.length);
      outputStream = response.getOutputStream();
      outputStream.write(data);
      outputStream.flush();
    } catch (Exception e) {
      logger.error("下载p10证书出错,读写错误", e);
      throw new CodeException("", "下载p10证书出错", e);
    } finally {
      try {
        if (outputStream != null) {
          outputStream.close();
          outputStream = null;
        }
      } catch (IOException e) {
      }
    }
  }

  @RequestMapping(value={"/v_importCert"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
  public String viewImportCertPage(String certID, ModelMap modelMap, HttpServletRequest request) throws CodeException {
    try {
      SealCert sealCert = this.sealCertService.getSealCertById(certID);
      modelMap.put("device", sealCert.getDevice());
      modelMap.put("id", sealCert.getId());
      modelMap.put("alias", sealCert.getAlias());
      return this.jumpImportCertPath;
    } catch (Exception e) {
      logger.error("导入印章证书出现系统错误", e);
      throw new CodeException("C0001", e);
    }
  }

  @RequestMapping(value={"/o_importCert"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
  public String importServerCert(String certID, @RequestParam("sealCert") CommonsMultipartFile sealCert, String confirmPassword, ModelMap modelMap, HttpServletRequest request) throws CodeException
  {
    OperationLog operationLog = OperationLogManager.getInstance(request, "印章证书管理", "导入服务器证书", "", "导入服务器证书", null);
    operationLog.setOrganizationId(SessionManager.getManager(request).getOrganizationId());
    SealCert sealCert2 = new SealCert();
    try {
      if (sealCert.isEmpty()) {
        modelMap.put("error", "请加入公钥证书。");
        viewImportCertPage(certID, modelMap, request);
      } else if (!sealCert.getFileItem().getName().toLowerCase().endsWith(".cer")) {
        modelMap.put("error", "公钥证书后缀必须是cer格式。");
        viewImportCertPage(certID, modelMap, request);
      }
      sealCert2 = this.sealCertService.getSealCertById(certID);
      this.sealCertService.importCert(sealCert.getBytes(), sealCert2, confirmPassword);
    } catch (CodeException e) {
      operationLog.setResult(10);
      logger.error(e.getMessage(), e);
      modelMap.put("error", e.getMessage());
      return viewImportCertPage(certID, modelMap, request);
    }
    catch (Exception e)
    {
      String str;
      operationLog.setResult(10);
      logger.error("导入证书失败:", e);
      modelMap.put("error", "内部异常");
      return viewImportCertPage(certID, modelMap, request);
    } finally {
      operationLog.setObjectId(sealCert2.getAlias());
      this.operationLogService.addOperationLog(operationLog);
    }

    return this.jumplistdo;
  }

  @RequestMapping(value={"/v_detail/{certID}"}, method={org.springframework.web.bind.annotation.RequestMethod.GET})
  public String viewDetailPage(@PathVariable("certID") String certID, ModelMap modelMap, HttpServletRequest request) throws CodeException {
    try {
      SealCert sealCert = this.sealCertService.getSealCertById(certID);
      this.sealCertService.addAdditionInfo(sealCert);
      modelMap.put("sealCert", sealCert);
      return this.jumpCertDetailPath;
    } catch (Exception e) {
      logger.error("查看印章证书信息出现系统错误", e);
      throw new CodeException("C0001", e);
    }
  }

  @RequestMapping({"/o_add"})
  public String add(SealCert sealCert, ModelMap modelMap, HttpServletRequest request) throws CodeException {
    OperationLog operationLog = OperationLogManager.getInstance(request, "印章证书管理", "增加", "", "添加印章证书", null);
    operationLog.setOrganizationId(SessionManager.getManager(request).getOrganizationId());
    try {
      sealCert.setId(StringUtil.generateID());
      sealCert.setImportDate(new Date());
      boolean resultInfo = this.sealCertService.addSealCert(sealCert);
      modelMap.put("resultInfo", Boolean.valueOf(resultInfo));
      return this.jumplistdo;
    } catch (Exception e) {
      operationLog.setResult(10);
      logger.error("添加印章证书出现系统错误", e);
      throw new CodeException("C0001", e);
    } finally {
      operationLog.setObjectId(sealCert.getAlias());
      this.operationLogService.addOperationLog(operationLog);
    }
  }

  @RequestMapping({"/o_delete"})
  public String delete(String certID, String alias, ModelMap modelMap, HttpServletRequest request) throws CodeException {
    OperationLog operationLog = OperationLogManager.getInstance(request, "印章证书管理", "删除", "", "删除印章证书", null);
    operationLog.setOrganizationId(SessionManager.getManager(request).getOrganizationId());
    try
    {
      boolean resultInfo = this.sealCertService.deleteById(certID);
      modelMap.put("resultInfo", Boolean.valueOf(resultInfo));
      return this.jumplistdo;
    } catch (CodeException ce) {
      operationLog.setResult(10);
      logger.error("删除印章证书出现系统错误", ce);
      throw new CodeException(ce.getCode(), ce.getMessage());
    } catch (Exception e) {
      operationLog.setResult(10);
      logger.error("删除印章证书出现系统错误", e);
      throw new CodeException("C0001", e);
    } finally {
      operationLog.setObjectId(alias);
      this.operationLogService.addOperationLog(operationLog);
    }
  }
}